﻿using System;
using System.Threading;
using System.ComponentModel;

namespace CMN.Domain
{


   
    /// <summary>
    /// 线程事件参数
    /// </summary>
     internal class AsyncEventArgs : EventArgs
    {
        private  int m_action;
        
        private readonly object[] m_objects;
        public int action
        {
            get { return this.m_action; }
        }
        public object[] getObjects
        {
            get { return this.m_objects; }
        }
        
        public AsyncEventArgs(int action,  object[] objs)
        {
            this.m_action = action;
            this.m_objects = objs;
           
        }
    }

    /// <summary>
    /// 异步操作基类,基类不需要修改，任务应该在子类中完成
    /// 注意：只适用用winform开发
    /// </summary>
    public abstract class AsyncBase
    {
        private Thread m_thread;
        private readonly ISynchronizeInvoke m_Target;
        private bool m_IsStop = false;
        private bool[] m_isCancelFlag = new bool[]{false,false};
        protected int m_action = 0;        

        public event EventHandler TaskBefore;
        public event EventHandler TaskProgress;
        public event EventHandler TaskDone;
        public event EventHandler Complete;
        public event EventHandler Error;

        //开始执行任务之前
        private void OnTaskBefore(object sender)
        {
            toTarget(TaskBefore, new object[] { sender, new AsyncEventArgs(this.m_action, null) });
        }

        //执行任务进度
        protected void OnTaskProgress(object sender, int step)
        {
            toTarget(TaskProgress, new object[] { sender, new AsyncEventArgs(this.m_action, new object[] { step }) });
        }

        //执行任务成功完成（只有任务成功才会执行，取消和异常均不会执行），传递给主线程的对象在这里设置
        protected void OnTaskDone(object sender, object[] objs)
        {
            toTarget(TaskDone, new object[] { sender, new AsyncEventArgs(this.m_action, objs) });
        }

        //执行任务时发生异常
        private void OnError(object sender, Exception exp)
        {
            toTarget(Error, new object[] { sender, new AsyncEventArgs(this.m_action, new object[] { exp }) });
        }

        //完成一个任务，无论如果都会执行
        private void OnComplete(object sender)
        {
            toTarget(Complete, new object[] { sender, new AsyncEventArgs(this.m_action, null) });
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="Target">调用目标</param>
        protected AsyncBase(ISynchronizeInvoke target)
        {
            this.m_Target = target;
            this.m_thread = null;
        }


        ~AsyncBase()
        {
            Stop();
        }


        //启动一个工作线程
        public void Start()
        {
            try
            {
                this.m_thread = new Thread(new ThreadStart(Work));
                this.m_thread.Start();
            }
            catch (Exception e)
            {
                this.m_thread = null;
                throw e;
            }// catch
           
        }// end void

        //停止一个工作线程
        public void Stop()
        {
            if (null == this.m_thread) 
                return;
            /*取消并等待任务完成*/
          
            if (this.m_isCancelFlag[1])
            {
                this.m_isCancelFlag[0] = true;
               
            }
           
            this.m_IsStop = true;
           
           // this.m_thread.Join();

            
            //this.m_isCancelFlag[0] = false;
            //this.m_isCancelFlag[1] = false;
            //this.m_IsStop = false;
            
            this.m_thread = null;
        }

        //取消一个支持取消功能的任务（必须支持取消功能）
        public void cnacelTask()
        {
            Monitor.Enter(this);
            this.m_isCancelFlag[0] = true;
           
        }

        /// <summary>
        /// 工作方法
        /// </summary>
        private void Work()
        {
            bool isStop = false;
                   //send signal thread start
            while (!isStop)
            {
                //Monitor.Wait(this);         //wait task and unlock
                //lock
                this.m_isCancelFlag[0] = false;
                this.m_isCancelFlag[1] = false;
                isStop = this.m_IsStop;
                if (!isStop)
                    Workex();
              
            }
            
                    //unlock
        }// end void

        //工作方法
        private void Workex()
        {
            try
            {
                OnTaskBefore(this);
                AsyncWork();
            }
            catch (Exception e)
            {
                OnError(this, e);
            }// catch
            finally
            {
                this.m_isCancelFlag[0] = false;
                this.m_isCancelFlag[1] = false;
                this.m_action = 0;
               
                OnComplete(this);
            }// end finally
        }

        //实现多线程任务
        protected abstract void AsyncWork();

        //在子类中调用，获取可以取消的任务是否取消
        protected bool isCnacel()
        {
            if ( !this.m_isCancelFlag[1])
                this.m_isCancelFlag[1] = true;
            bool is_cnacel = this.m_isCancelFlag[0];
          
            return is_cnacel;
        }

        //回到主线程上执行委托
        private void toTarget(Delegate dlg, params object[] paras)
        {
            if (this.m_Target != null)
            {
                if (dlg != null)
                    this.m_Target.BeginInvoke(dlg, paras);
            }
            else
            {
                throw new Exception("在线程运行结束之前，调用目标已经关闭，调用目标必须等待线程运行完成后才能关闭！");
            }
        }

    }
}
